# -*- coding: utf-8 -*-
# Copyright (c) 2005-2006 The Regents of The University of Michigan
# All rights reserved.
# Copyright (c) 2009-2010 Microelectronic Center, Harbin Institute
# Technology
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are
# met: redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer;
# redistributions in binary form must reproduce the above copyright
# notice, this list of conditions and the following disclaimer in the
# documentation and/or other materials provided with the distribution;
# neither the name of the copyright holders nor the names of its
# contributors may be used to endorse or promote products derived from
# this software without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#
# Authors: Gou Pengfei
#

import matplotlib
import pylab
from matplotlib.font_manager import FontProperties
from numpy import array, arange, reshape, shape, transpose, zeros
from numpy import float
from matplotlib.ticker import NullLocator
from matplotlib import rc

matplotlib.interactive(False)
#matplotlib.use('cairo.pdf')

chfont = \
matplotlib.font_manager.FontProperties(family='SimSun',
                                       fname='/home/pengfei/.fonts/simsun.ttc')

enfont = \
matplotlib.font_manager.FontProperties(family='times',
                                       fname='/home/pengfei/.fonts/times.ttf')

from chart import ChartOptions

marker_table = [
                'o', 
                'v',
                '^',
                '<',
                '>',
                's',
                'p',
                '*',
                'h',
                'H',
                '+',
                'x',
                'D',
                'd',
                '|',
                '_',
                ',',   
                '1',
                '2',
                '3',
                '4',
                '.'
                ]

class PlotChart(ChartOptions):
    def __init__(self, default=None, **kwargs):
        super(PlotChart, self).__init__(default, **kwargs)
        self.inputdata = None
        self.chartdata = None
        self.inputerr = None
        self.charterr = None

    def gen_colors(self, count):
        cmap = matplotlib.cm.get_cmap(self.colormap)
        if count == 1:
            return cmap([ 0.5 ])

        if count < 5:
            return cmap(arange(5) / float(4))[:count]

        return cmap(arange(count) / float(count - 1))

    def gen_markers(self,count):

        marker_num = len(marker_table)
        if count <= marker_num:
            return marker_table[:count]
        else:
            markers = marker_table + marker_table[:count-marker_num]

    def set_data(self, data):
        if data is None:
            self.inputdata = None
            self.chartdata = None
            return

        data = array(data)
        dim = len(shape(data))
        if dim not in (1, 2):
            raise AttributeError, "Input data must be a 1 or 2 matrix"
        self.inputdata = data

        self.chartdata = data

    def get_data(self):
        return self.inputdata

    data = property(get_data, set_data)

    def graph(self):
        print 'graphing'
        if self.chartdata is None:
            raise AttributeError, "Data not set for plot chart!"

        matplotlib.rcParams['font.size'] = 10.5
        matplotlib.rcParams['font.serif'] = 'Times New Roman'
        matplotlib.rcParams['font.sans-serif'] = 'Times New Roman'

        dim = len(shape(self.inputdata))
        cshape = shape(self.chartdata)

        colors = self.gen_colors(cshape[0])
        markers = self.gen_markers(cshape[0])

        colors = array(colors)

        self.figure = pylab.figure(figsize=self.chart_size)
        self.figure.patch.set_alpha(0.0)

#        subplot = self.figure.add_subplot(111, axisbg='.6')
#        axes = self.figure.add_axes(self.figure_size, axisbg='.6')
        axes = self.figure.add_axes(self.figure_size)
        self.axes = axes

        lines_in_group = len(self.chartdata)

        lines = []
        max_data = []
        min_data = []
        max_x = []
        for i,linedata in enumerate(self.chartdata):

            num_x = len(linedata)

            max_temp = max(linedata)
            min_temp = min(linedata)

            x = arange(0, num_x)

            line = axes.plot(x, linedata, marker = markers[i], linestyle = '-',
#                                color=colors[i],
                                markersize = 5,
                                linewidth = 0.5)
            lines.append(line)
            max_data.append(max_temp)
            min_data.append(min_temp)
            max_x.append(num_x)

        #axes.set_ylim(ymax=(max(max_data)*1.1))
        axes.set_ylim(ymax=(max(max_data)*1.1))
#        axes.set_ylim(ymin=(min(min_data)*1))

        if self.ygrid:
            axes.yaxis.grid(True)

        if self.xgrid:
            axes.xaxis.grid(True)

#        if self.xticks is not None:
#            axes.set_xticklabels(self.xticks, rotation = self.xlabel_rotation)
#            axes.set_xticks(range(0, max(max_x)))
#            axes.set_xticklabels(self.xticks, rotation = self.xlabel_rotation,
#                                fontproperties=enfont)

        if self.legend is not None:

            if self.fig_legend:
                leg = self.figure.legend(lines, self.legend, self.legend_loc,
                                   prop=FontProperties(size=self.legend_size),
                                   )
                leg_frame = leg.get_frame()
#                leg_frame.set_facecolor('.6')
            else:
                leg = self.axes.legend(lines, self.legend, self.legend_loc,
                                 prop=FontProperties(size=self.legend_size),
                                 )
                leg_frame = leg.get_frame()
#                leg_frame.set_facecolor('.6')

        if self.title is not None:
            self.axes.set_title(self.title)

        if self.xlabel is not None:
            axes.set_xlabel(self.xlabel, fontproperties=chfont)

        if self.ylabel is not None:
            axes.set_ylabel(self.ylabel, fontproperties=chfont)

    def savefig(self, name):
        self.figure.savefig(name)

    def savecsv(self, name):
        f = file(name, 'w')
        data = array(self.inputdata)
        dim = len(data.shape)

        if dim == 1:
            #if self.xlabel:
            #    f.write(', '.join(list(self.xlabel)) + '\n')
            f.write(', '.join([ '%f' % val for val in data]) + '\n')
        if dim == 2:
            #if self.xlabel:
            #    f.write(', '.join([''] + list(self.xlabel)) + '\n')
            for i,row in enumerate(data):
                ylabel = []
                #if self.ylabel:
                #    ylabel = [ self.ylabel[i] ]
                f.write(', '.join(ylabel + [ '%f' % v for v in row]) + '\n')
        if dim == 3:
            f.write("don't do 3D csv files\n")
            pass

        f.close()

